package com.shop.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.ex.ShoppingException;
import com.shop.feignClient.DiscountClient;
import com.shop.feignClient.GoodsClient;
import com.shop.po.Discount;
import com.shop.po.R;
import com.shop.po.dto.OrderDetailInfo;
import com.shop.user.Interceptor.GetUserInfoInterceptor;
import com.shop.user.handler.CreateOrderIdHandler;
import com.shop.user.mapper.*;
import com.shop.user.mqHandler.sentMessage.OrderCancelHandler;
import com.shop.user.po.*;
import com.shop.user.po.dto.OrderInfo;
import com.shop.user.service.AddressBookService;
import com.shop.user.service.OrderDetailService;
import com.shop.user.service.OrderService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author banxia
 * @since 2023-02-25
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private OrderDetailService orderDetailService;

    private StringRedisTemplate redisTemplate;

    @Autowired
    CreateOrderIdHandler createOrderIdHandler;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private DiscountUserMapper discountUserMapper;

    @Autowired
    private DiscountClient discountClient;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private OrderCancelHandler orderCancelHandler;


    @Autowired
    private AddressBookService addressBookService;

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        if (orderId==null) ShoppingException.ThrowShoppingException("订单id不存在");
        OrderInfo orderInfo=orderMapper.getOrderInfo(orderId);
        //获取到地址
        Long addressId = orderInfo.getAddressId();
        AddressBook addressBook = addressBookService.getById(addressId);
        orderInfo.setAddressBooke(addressBook);
        return orderInfo;
    }

    @Override
    @Transactional
    public void choiceDiscount(Long orderId, Long discountId) {
        User user = GetUserInfoInterceptor.getUser();
        if (user == null) {
            ShoppingException.ThrowShoppingException("请先登录");
        }
        int i=discountUserMapper.deleteUserDiscount(user.getId(),discountId);
        if (i == 0) {
            ShoppingException.ThrowShoppingException("该用户不存在该优惠券");
        }
        //获取优惠券信息
        Discount discount = discountClient.getDiscountById(discountId);
        Date now = new Date();
        //校验是否到达begin_time
        if (discount.getBeginTime().after(now)){
            ShoppingException.ThrowShoppingException("该优惠券暂时还不可以使用，请稍等几天");
        }
        //校验是否过了end_time
        if (discount.getEndTime().before(now)){
            ShoppingException.ThrowShoppingException("该优惠券已过期......");
        }
        //获取分布式锁
        String redisLock="user:choid:discount"+orderId;
        RLock lock = redissonClient.getLock(redisLock);
        if (!lock.tryLock()){
            //抢不到锁，直接error
            ShoppingException.ThrowShoppingException("订单修改优惠券失败，请重试");
        }
        try {
            //查看原先订单是否存在优惠券
            Orders orders = orderMapper.selectById(orderId);
            if (orders == null) {
                ShoppingException.ThrowShoppingException("该订单不存在！");
            }
            if (orders.getDiscountId() != null) {
                //存在优惠券，对该优惠券进行回填
                LambdaQueryWrapper<DiscountUser> wrapper=new LambdaQueryWrapper();
                Long discountId1 = orders.getDiscountId();
                wrapper.eq(DiscountUser::getDiscountId,discountId1);

                DiscountUser discountUser = new DiscountUser();
                discountUser.setCount(1L);
                wrapper.eq(DiscountUser::getUserId,user.getId());
                discountUserMapper.update(discountUser,wrapper);
            }
            //修改订单记录（大于使用门槛才可以使用）
            int j=orderMapper.changeDiscount(orderId,discountId,discount.getMinPrice(),discount.getDiscountPrice());
            if (j == 0) {
                ShoppingException.ThrowShoppingException("修改订单表记录失败");
            }
        } finally {
            lock.unlock();
        }
    }

    @Override
    @Transactional
    public void createOrder(List<Long> cartIdList,Long addressId,String remarks) {
        User user = GetUserInfoInterceptor.getUser();
        if (user==null){
            ShoppingException.ThrowShoppingException("请先登录");
        }
        Orders orders = new Orders();
        //生出订单表的ID（通过redis生成全局唯一ID）
        Long idByredis= createOrderIdHandler.nextId();
        orders.setOrderId(idByredis);
        //根据购物车id查询到对应的商品
        List<Cart> carts = cartMapper.selectBatchIds(cartIdList);
        List<OrderDetail> orderDetailList=new ArrayList<>(carts.size());
        Long totalAmount=0L;//该订单的总金额
        if (carts.size()==0){
            ShoppingException.ThrowShoppingException("请选择正确的商品（购物车ID为空或无效）");
        }
        for (Cart cart : carts) {
            OrderDetail od = new OrderDetail();
            orderDetailList.add(od);
            od.setGoodsBaseId(cart.getGoodsBaseId());
            od.setGoodsBaseName(cart.getGoodsBaseName());
            od.setGoodsImagePath(cart.getGoodsImagePath());
            od.setMerchantId(cart.getMerchantId());
            od.setMerchantName(cart.getMerchantName());
            od.setCount(cart.getCount());
            od.setOnePrice(cart.getPriceIdOldPrice());
            Long OneTotalPrice =0L;//单个商品的总金额：数量*单价
            OneTotalPrice=cart.getCount()*cart.getPriceIdOldPrice();
            totalAmount+=OneTotalPrice;
            od.setTotalPrice(OneTotalPrice);
            od.setOrderId(idByredis);
            //删除购物车数据
            int i = cartMapper.deleteById(cart.getId());
            if (i == 0) {
                ShoppingException.ThrowShoppingException("购物车数据删除失败，请重试");
            }
            //----------------------------------------------------------------
            //修改库存,若库存修改失败，那么就抛异常！！订单生成直接回滚
            R r = goodsClient.goodsCountUpdate(cart.getGoodsBaseId(), (long)- cart.getCount());
//            if (r.getCode()!=200){
            if (!r.getCode().equals(200)){
                ShoppingException.ThrowShoppingException(cart.getGoodsBaseName()+"-库存不够");
            }
        }
        //插入订单详情表
        orderDetailService.saveBatch(orderDetailList);
        //插入订单总体表
        orders.setTotalAmount(totalAmount);
        orders.setNeedAmount(totalAmount);
        orders.setRemarks(remarks);
        orders.setAddressId(addressId);
        orders.setUserId(user.getId());
        orders.setState("0");
        int j = orderMapper.insert(orders);
        if (j == 0) {
            ShoppingException.ThrowShoppingException("订单表插入失败");
        }
        //死信交换机->30分钟未支付则取消订单
        orderCancelHandler.sendToExchange(orders.getId().toString());
    }

    @Override
    public List<OrderInfo> getUserOrders(String state) {
        User user = GetUserInfoInterceptor.getUser();
        if (user==null || user.getId()==null) ShoppingException.ThrowShoppingException("请先登录");
        LambdaQueryWrapper<Orders> query = new LambdaQueryWrapper();
        query.eq(Orders::getUserId,user.getId());
        //state为0，1，2，或为全部
        if (state.equals("0") || state.equals("1") || state.equals("2")){
            query.eq(Orders::getState,state);
        }
        List<Orders> orders = orderMapper.selectList(query);
        //依次获取到各个订单表的详细信息
        List<OrderInfo> res=new ArrayList<>(orders.size());
        for (Orders order : orders) {
            OrderInfo orderInfo = getOrderInfo(order.getId());
            res.add(orderInfo);
        }
        return res;
    }

    @Override
    public void pay(Long id) {
        Orders orders = new Orders();
        orders.setState("1");
        orders.setId(id);
        int i = orderMapper.updateById(orders);
        if (i==0){
            ShoppingException.ThrowShoppingException("支付失败");
        }
        Orders orders1 = orderMapper.selectById(id);
        orderDetailMapper.updateState(orders1.getOrderId(),"1");
    }

    //查询订单状态
    @Override
    public List<OrderDetailInfo> merchantGetOrderInfo(Long merchantId, String state,Long page,Long size) {
        //page为当前第几页
        Long start=(page-1)*size;
        return orderDetailMapper.merchantGetOrderInfo(merchantId,state,start,size);
    }

    @Override
    public Long merchantGetTotal(Long merchantId, String state) {
        return orderDetailMapper.merchantGetTotal(merchantId,state);
    }

    @Override
    public void changState(String state, String orderDetailsId) {
        orderDetailMapper.changState(state,orderDetailsId);
    }

}
